package com.swind.fast.modules.app.halali.customer.service.impl;

import com.swind.fast.common.util.oConvertUtils;
import java.util.stream.Collectors;
import com.swind.fast.modules.app.halali.customer.entity.Order;
// import com.swind.fast.modules.app.halali.customer.entity.OrderBill;
import com.swind.fast.modules.app.halali.customer.mapper.OrderMapper;
import com.swind.fast.modules.app.halali.customer.service.IOrderService;
import com.swind.fast.common.system.vo.HalaliLoginUser;

import com.swind.fast.modules.app.halali.customer.entity.UserAddress;
import com.swind.fast.modules.app.halali.customer.service.IUserAddressService;
import com.swind.fast.modules.app.halali.customer.entity.OrderItem;
import com.swind.fast.modules.app.halali.customer.service.IOrderItemService;
import com.swind.fast.modules.app.halali.customer.entity.RestaurantMeal;
import com.swind.fast.modules.app.halali.customer.service.IRestaurantMealService;

import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.ApplicationContext;
import org.apache.shiro.SecurityUtils;

import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.swind.fast.modules.app.halali.customer.vo.response.CartPriceVo;
import com.swind.fast.modules.app.halali.customer.vo.response.OrderDetailVo;

import cn.hutool.core.date.DateBetween;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;

import javax.annotation.Resource;

import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Optional;

import com.swind.fast.modules.app.halali.customer.vo.request.OrderVo;
import com.swind.fast.modules.app.halali.customer.vo.common.ServiceHint;

/**
 * @Description: 项目
 * @Author: swind
 * @Date:   2021-11-20
 * @Version: V1.0
 */
@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private IUserAddressService userAddressService;

    @Autowired
    private IOrderItemService orderItemService;

    @Autowired
    private IRestaurantMealService restaurantMealService;

    public Order buildOrder(CartPriceVo cartPrice, List<OrderItem> orderItems) {
        Order order = this.saveMain(cartPrice, orderItems);

        // 保存订单详情条目
        // orderItemService.saveBatch(orderItems);
        return order;
    }

    public Order saveMain(CartPriceVo cartPrice, List<OrderItem> orderItems) {
        Order order = new Order();
        order.setTitle("DRAFT0000000H");
        order.setServiceFee(cartPrice.getServiceFee());
        order.setDeliveryFee(cartPrice.getDeliveryFee());
        order.setDiscount(cartPrice.getDiscount());
        order.setVoucher(cartPrice.getVoucher());
        order.setTotalPrice(cartPrice.getTotalPrice());
        order.setState("Draft");

        if (orderItems.size() > 0) {
            OrderItem item = (OrderItem) orderItems.get(0);
            String restaurantId = item.getRestaurantId();
            order.setRestaurantId(restaurantId);
        }

        HalaliLoginUser loginUser = (HalaliLoginUser) SecurityUtils.getSubject().getPrincipal();
        if (oConvertUtils.isNotEmpty(loginUser)) {
            order.setUserId(loginUser.getId());
        }

        this.save(order);

        return order;
    }

    public Order confirm(OrderVo order) {
        if (oConvertUtils.isEmpty(order.getId()) || oConvertUtils.isEmpty(order.getAddressId())) {
            return null;
        }

        UpdateWrapper<Order> itemWrapper = new UpdateWrapper<Order>().set("address_id", order.getAddressId()).set("state", "Preparing").eq("id", order.getId());
        this.update(itemWrapper);

        Order retOrder = this.getById(order.getId());
        return retOrder;
    }

    public IPage<Order> renderPage(IPage<Order> pageList) {
        List<Order> orders = (List<Order>) (pageList.getRecords());
        if (orders.size() < 1) {
            return pageList;
        }
        List<String> ids = orders.stream().map(Order::getId).collect(Collectors.toList());

        QueryWrapper<OrderItem> itemWrapper = new QueryWrapper<OrderItem>().in("order_id", ids);
        List<OrderItem> items = orderItemService.list(itemWrapper);
        if (oConvertUtils.isEmpty(items)) {
            return pageList;
        }

        // 获取MealIds
        List<String> tids = items.stream().map(OrderItem::getMealId).collect(Collectors.toList());
        List<RestaurantMeal> meals = restaurantMealService.listByIds(tids);

        if (oConvertUtils.isNotEmpty(meals)) {
            for (Order order : orders) {
                List<OrderItem> oitems = items.stream().filter(e -> (e.getOrderId().equals(order.getId()))).collect(Collectors.toList());
                List<String> pids = oitems.stream().map(OrderItem::getMealId).collect(Collectors.toList());
                List<RestaurantMeal> pmeals = meals.stream().filter(e -> (pids.contains(e.getId()))).collect(Collectors.toList());
                order.setItems(pmeals);
            }
        }
        pageList.setRecords(orders);
        return pageList;
    }

    public OrderDetailVo getDetailById(String id) {

        // HalaliLoginUser loginUser = (HalaliLoginUser) SecurityUtils.getSubject().getPrincipal();
        // log.info("====loginUser: {}", loginUser);

        OrderDetailVo orderDetail = new OrderDetailVo();

        if (oConvertUtils.isEmpty(id)) {
            return orderDetail;
        }

        Order order = this.getById(id);
        orderDetail.setOrder(order);
        if (oConvertUtils.isEmpty(order.getAddressId())) {
            return orderDetail;
        }

        UserAddress address = userAddressService.getById(order.getAddressId());
        if (oConvertUtils.isNotEmpty(order.getAddressId())) {
            orderDetail.setAddress(address);
        }

        QueryWrapper<OrderItem> itemWrapper = new QueryWrapper<OrderItem>().eq("order_id", id);
        List<OrderItem> items = orderItemService.list(itemWrapper);
        if (oConvertUtils.isEmpty(items)) {
            return orderDetail;
            // orderDetail.setItems(items);
        }

        // 获取MealIds
        List<String> ids = items.stream().map(OrderItem::getMealId).collect(Collectors.toList());
        List<RestaurantMeal> meals = restaurantMealService.listByIds(ids);
        if (oConvertUtils.isNotEmpty(meals)) {
            // 获取订单数目
            // List<RestaurantMeal> retMeals = new ArrayList<RestaurantMeal>();
            for (RestaurantMeal meal : meals) {
                Optional<OrderItem> itemOpt = items.stream().filter(p -> p.getMealId().equals(meal.getId())).findFirst();
                if (itemOpt.isPresent()) {
                    OrderItem orderItem = itemOpt.get();
                    if (oConvertUtils.isNotEmpty(orderItem.getNum())) {
                        meal.setQuantity(orderItem.getNum().toString());
                    }

                }

                // retMeals.add(meal);
            }
            orderDetail.setItems(meals);
        }

        // 获取文案提示信息
        List<ServiceHint> hints = new ArrayList<ServiceHint>();
        for (int i = 0; i < 3; i++) {
            ServiceHint hint = new ServiceHint();
            hint.setTitle("Service Fee");
            hint.setPrice("$10.00");
            hint.setDesc("ervice fee for the order Service fee for the orderService fee for the orderService fee for the orderService fee for the order");
            hints.add(hint);
        }
        orderDetail.setHints(hints);

        return orderDetail;
    }
}
